package com.fang.system.rpc.handler;

import com.fang.system.rpc.dispatcher.Dispatcher;
import com.fang.system.rpc.model.MyContent;
import com.fang.system.rpc.model.MyHeader;
import com.fang.system.rpc.model.PackageMsg;
import com.fang.system.rpc.util.SerDerUtil;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.PooledByteBufAllocator;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;

import java.io.ByteArrayInputStream;
import java.io.ObjectInputStream;
import java.lang.reflect.Method;
import java.util.Arrays;

/**
 * @author fanglingxiao
 * @version 1.0
 * @description TODO
 * @date 2022/7/16 11:09 下午
 **/
public class ServerRequestHandler extends ChannelInboundHandlerAdapter {

    private Dispatcher dispatcher;

    public ServerRequestHandler(Dispatcher dispatcher) {
        this.dispatcher = dispatcher;
    }

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
//        System.out.println("server handler接收到数据。。。。");
//        ByteBuf byteBuf = (ByteBuf) msg;
//        int headSize = 110;
//        while (byteBuf.readableBytes() >= headSize) {
//            // 反序列化解析Header
//            byte[] bytes = new byte[headSize];
//            // 从哪里读取，读多少，但是readIndex不变
//            byteBuf.getBytes(byteBuf.readerIndex(), bytes);
//            ByteArrayInputStream in = new ByteArrayInputStream(bytes);
//            ObjectInputStream oin = new ObjectInputStream(in);
//            //
//            PackageMsg packageMsg = (PackageMsg) oin.readObject();
//
//            byte[] packageByte = SerDerUtil.ser(packageMsg);
//
//            ByteBuf buf = PooledByteBufAllocator.DEFAULT.directBuffer(packageByte.length);
//
//            buf.writeBytes(packageByte);
//            ctx.writeAndFlush(buf);
//        }
        PackageMsg requestPkg = (PackageMsg) msg;
        System.out.println("server handler接收到数据 :" + Arrays.toString(requestPkg.getContent().getArgs()));
        String threadName = Thread.currentThread().getName();
        // 使用netty的eventLoop来处理业务并且返回
        ctx.executor().execute(() -> {
            try {
                String serviceName = requestPkg.getContent().getInterfaceName();
                String methodName = requestPkg.getContent().getMethodName();
                Object obj = dispatcher.get(serviceName);

                Class<?> clazz = obj.getClass();
                Method method = clazz.getMethod(methodName, requestPkg.getContent().getParameterTypes());
                Object response = method.invoke(obj, requestPkg.getContent().getArgs());

                MyContent content = new MyContent();
                content.setRes((String) response);
                byte[] contentByte = SerDerUtil.ser(content);

                MyHeader resHeader = new MyHeader();
                resHeader.setFlag(requestPkg.getHeader().getFlag());
                resHeader.setRequestId(requestPkg.getHeader().getRequestId());
                resHeader.setDataLen(contentByte.length);
                byte[] resHeaderByte = SerDerUtil.ser(resHeader);
                ByteBuf buf = PooledByteBufAllocator.DEFAULT.directBuffer(resHeaderByte.length + contentByte.length);

                buf.writeBytes(resHeaderByte);
                buf.writeBytes(contentByte);
                ctx.writeAndFlush(buf);

            } catch (Exception e) {
                e.printStackTrace();
            }
        });
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        super.exceptionCaught(ctx, cause);
        if (ctx.channel().isActive()) {
            ctx.close();
        }
    }
}
